home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / AUDIOPLAYERS / AMP / !Amp / Docs / Extbasdoc < prev    next >
Text File  |  1998-03-01  |  15KB  |  471 lines

  1. Extended BASIC Assembler
  2. ————————————————————————
  3. Version 1.77, 1 March 1998
  4. by Darren Salt <arcsalt@spuddy.mew.co.uk>
  5. Contains code from v1.00 and v1.30 by Adrian Lees
  6.  
  7.  
  8. It is recommended that you read through this document before first using
  9. ExtBASICasm, and check through it quickly when upgrading. It's entirely
  10. possible that one of the extras the module provides may cause a clash with
  11. existing programs, for example the APCS-R register names clashing with
  12. variables used as register names.
  13.  
  14. Note also that APCS-R register names are disabled by default.
  15.  
  16.  
  17. The module ExtBASICasm provides a patch for versions 1.05, 1.06, 1.14 and
  18. 1.16 of BASIC V, as supplied with RISC OS 3.1, 3.5, 3.6 and 3.7 respectively,
  19. to allow the direct use of the extra instructions provided by the ARM3, ARM6,
  20. ARM7, ARM8 and StrongARM processors. The missing floating-point and general
  21. coprocessor instructions, and some assembler directives more familiar (and a
  22. few unfamiliar) to Acorn Assembler users have been added; also the APCS-R
  23. register names may be used.
  24.  
  25. To make the necessary changes to the BASIC module it must be located in RAM.
  26. The ExtBASICasm module will therefore attempt to RMFaster the BASIC module
  27. which will require a small amount of memory in the RMA, in addition to that
  28. required by the ExtBASICasm module itself. Attempting to run it while BASIC
  29. is active and in ROM will not work - try "*RMFaster BASIC" at the BASIC
  30. prompt and you'll see why.
  31.  
  32.  
  33. Enabling ExtBASICasm
  34. ————————————————————
  35.  
  36. Unlike earlier versions, this version is initialised into a dormant state
  37. whenever you start up the BASIC interpreter, eg. by double-clicking on a
  38. BASIC program or by typing BASIC at the * prompt.
  39.  
  40. You can enable or disable the extensions by using the assembler pseudo-op
  41.     EXT n
  42. where n is 0 to disable and 1 to enable. (Other values are currently mapped
  43. to 1; do not rely on this.)
  44.  
  45. Setting any of the three extension OPT bits is also enough to enable
  46. ExtBASICasm.
  47.  
  48. Certain extensions remain enabled at all times: specifically, ALIGN always
  49. zero-fills, and the ".foo = bar" bug remains fixed. I don't think that
  50. this'll inconvenience anybody :-)
  51.  
  52.  
  53. ExtBASICasm uses the BASIC data word TIMEOF, which is documented as "unused"
  54. for all versions of BASIC V which it recognises, for its 'enabled' flag.
  55.  
  56.  
  57. The instructions added by the module are as follows:
  58.  
  59.  
  60. Extensions
  61. ——————————
  62.  
  63.     Optional parts are enclosed in {}
  64.  
  65. OPT    <value>
  66.     Bit 4:    ASSERT control (1 = enabled on 'second pass')
  67.     Bit 5:  APCS register names (1 = enabled)
  68.     Bit 6:    UMUL/UMULL control (0 = short forms, 1 = long forms)
  69.  
  70. ALIGN
  71.     Zero-initialises the memory if required.
  72.  
  73. ALIGN    <const>[,<const2>]
  74.     Aligns to a multiple of const bytes plus an optional offset. const
  75.     must be a power of 2 between 1 and 65536; const2 must be between 0
  76.     and const-1 (default is 0). Also zero-initialises the memory.
  77.     P% becomes (P% AND const-1)+const2; O% is also updated if necessary.
  78.     Examples:
  79.         ALIGN 4
  80.         ALIGN 32
  81.         ALIGN 16,8
  82.  
  83. MUL{cond}{S}    Rd,Rm,#<const>
  84.     variable length; Rd=Rm if <2 ADD/RSB
  85.     May cause 'duplicate register' if Rd=Rm and const is not simple - ie.
  86.     not 0, (2^x)-1, 2^x, (2^x)+(2^y)
  87.  
  88. MLA{cond}{S}    Rd,Rm,#<const>,Ra
  89.     variable length; Rd=Rm if <2 ADD/RSB
  90.     Rd=Ra causes 'duplicate register' error if const is not simple, as
  91.     for MUL; Rd=Rm=Ra is special in that MLA Rd,Rd,#c,Rd = MUL Rd,Rd,#c+1
  92.     If Rd=Ra and const=0, no code is generated (none necessary).
  93.  
  94. DIV        Rq,Rr,Rn,Rd,Rt [SGN Rs]
  95.     Integer division by register
  96.     Rq = quotient        Rn = numerator        Rt = temporary store
  97.     Rr = remainder        Rd = denominator    Rs = sign store
  98.     If Rs omitted then division is unsigned.
  99.     Rr may be same register as Rn *or* Rn may be same as Rs.
  100.     All other registers must be different.
  101.     Rt and Rs (if specified) are corrupted.
  102.  
  103. DIV        Rq,Rr,Rn,#d[,[Rt]] [SGN Rs]
  104.     Integer division by constant
  105.     Registers as above
  106.     If Rs omitted then division is unsigned.
  107.     If Rt omitted and is required for this division then error given.
  108.     All registers must be different.
  109.     If specified, Rt and Rs are corrupted.
  110.     (Uses generator to build code - fast but may be long)
  111.     Notes:    Uses Fourier method. For unsigned values, this is fixed to
  112.         handle unsigned top-bit-set properly, *except* for div by 3
  113.         which works for values up to &C0000000. Ideas and code
  114.         gratefully received...
  115.  
  116.     *** Note no conditional for either form of DIV!
  117.  
  118. ADR{cond}L    Rd,<const>
  119.     Fixed length (two words)
  120.  
  121. ADR{cond}X    Rd,<const>
  122.     Fixed length (three words)
  123.  
  124. ADR{cond}W    Rd,<const>
  125.     Addressing relative to R12, one to three words
  126.     <const> MUST be defined before it is used
  127.     Adds/subtracts const to/from R12, storing result in Rd
  128.     Up to you to ensure that R12 correctly set up...
  129.  
  130. LDR, STR
  131.     xxx{cond}{B}W    Rd,<offset>
  132.       Load/store word/byte at [R12,#<offset>]
  133.  
  134.     LDR{cond}{B}L    Rd,<address>
  135.     LDR{cond}{B}L    Rd,[Rm,#<offset>]{!}
  136.     LDR{cond}{B}WL    Rd,<offset>
  137.     STR equivalents
  138.       Addressing range is ±1MB; some offsets outside this range are also
  139.       valid. Lengths are (in words):
  140.         LDR        2  ADD/SUB Rd,Rm,#a:LDR Rd,[Rd,#b]
  141.         LDR ...]!  2  ADD/SUB Rd,Rm,#a:LDR Rd,[Rd,#b]!
  142.         STR        3  ADD/SUB Rm,Rm,#a:STR Rd,[Rm,#b]:SUB/ADD Rm,Rm,#a
  143.         STR ...]!  2  ADD/SUB Rm,Rm,#a:STR Rd,[Rm,#b]!
  144.  
  145.     LDR{cond}{B}L    Rd,{Rn},<address>
  146.     LDR{cond}{B}L    Rd,{Rn},[Rm,#<offset>]
  147.     LDR{cond}{B}WL    Rd,{Rn},<offset>
  148.     STR equivalents
  149.       [{Rn} is NOT optional]
  150.       Equivalent to the LDR/STRs above, except that Rn (rather than Rd)
  151.       is used to hold the address; always two words long. For example,
  152.       ADRL R0,wibble:LDR R1,[R0] may be replaced with LDRL R1,{R0},wibble
  153.       - one word shorter.
  154.       Rd=Rn is not allowed.
  155.       Assembles to ADD/SUB Rn,Rm,#a : LDR/STR Rd,[Rn,#b]!
  156.  
  157.     LDR{cond}{B}L    Rd,[Rm],#<offset>
  158.     STR equivalent
  159.       Addressing range is ±1MB; some offsets outside this range are also
  160.       valid. Two words long.
  161.       Assembles to LDR/STR Rd,[Rm],#b:ADD/SUB Rm,Rm,#a
  162.  
  163.     NOTE: You should try to avoid using *sequences* of LDRLs or STRLs -
  164.     there is usually a more efficient way.
  165.  
  166.     Also supported are the new ARM7M and StrongARM forms:
  167.     LDRxxH, LDRxxSH, LDRxxSB and STRxxH
  168.         The standard forms are used, with the following exceptions:
  169.             - no shifts
  170.             - constant offsets in range -255 to 255
  171.         The W forms are also supported.
  172.         Long LDR{H|SH|SB} not yet implemented.
  173.  
  174. SWAP{cond}[S]    Rd,Rn
  175.     Swaps Rd and Rn without using temporary store.
  176.     Uses EOR method, is therefore three words long.
  177.     If S is specified, then the flags are set according to Rn.
  178.  
  179. VDU{cond}{X}    <const>
  180.     = SWI "OS_WriteI"+<const>
  181.     With X present, XOS_WriteI is used instead.
  182.  
  183. NOP{cond}
  184.     = MOV{cond} R0,R0
  185.  
  186. BRK{cond} [#<const>]
  187.     Undefined instruction. If <const> is specified, then R14 is set to
  188.     this value before the undefined instruction trap is taken.
  189.  
  190. EQUx, DCx, =
  191.     xxx <value>[,<value>]^
  192.     Extended form of EQUD, EQUW, DCB, etc.
  193.     Instead of, eg. DCD 0 : DCD 12 : DCD branch
  194.     you can now use DCD 0, 12, branch
  195.  
  196. Negative constants
  197.     Allowed in the following instructions:
  198.         ADD, SUB    ADC, SBC    ADF, SUF
  199.         AND, BIC    MOV, MVN    MVF, MNF
  200.         CMP, CMN    CMF, CNF    CMFE, CNFE
  201.     If the constant is invalid for one of these, it is negated or
  202.     inverted, as appropriate, and the instruction changed to the other of
  203.     the pair (eg. ADC becomes SBC). If the constant is still invalid, the
  204.     "bad immediate constant" error is generated as normal.
  205.  
  206.  
  207. ARMv2a (ARM3, ARM250) and later
  208. ———————————————————————————————
  209.  
  210. SWP{cond}{B}    Rd,Rm,[Rn]
  211.  
  212.  
  213. ARMv3 (ARM6) and later
  214. ——————————————————————
  215.  
  216. MRS{cond}    Rd,<psr>
  217.     <psr> may only be CPSR or CPSR_all, or SPSR equivalents
  218.  
  219. MSR{cond}    <psr><f>,Rm
  220.     <psr> must be CPSR_ or SPSR_, and <f> must be one of the following:
  221.         _ctl    control bits only
  222.         _flg    flag bits only
  223.         _all    both
  224.     or a combination of _c, _x, _s, _f. _c_f, _cf, _f_c, _fc are all
  225.     equivalent to _all.
  226.  
  227.  
  228. ARMv4 (ARM8, StrongARM) and later
  229. —————————————————————————————————
  230.  
  231. UMUL, SMUL, UMLA, SMLA:
  232.     xxx{cond}{S}    Rl,Rh,Rm,Rn
  233.  
  234.     The 'official' forms UMULL, SMULL, UMLAL, SMLAL are used *instead of*
  235.     the 'short' forms if OPT bit 6 is set.
  236.     Unfortunately it's not possible to allow both forms at once: how
  237.     would you interpret "UMULLS" - UMUL condition LS or UMULL with S bit?
  238.  
  239.  
  240. Floating-point instructions
  241. ———————————————————————————
  242.  
  243. Floating point coprocessor data transfer
  244.  
  245. LDF, STF:
  246.     xxx{cond}prec    Fd,[Rn]{,#<offset>}
  247.     xxx{cond}prec    Fd,[Rn,#<offset>]{!}
  248.     xxx{cond}prec    Fd,<label | const>
  249.     xxx{cond}precW    Fd,<offset>
  250.  
  251. LFM, SFM:
  252.     xxx{cond}    Fd,m,[Rn]{,#<offset>}
  253.     xxx{cond}    Fd,m,[Rn,#<offset>]{!}
  254.     xxx{cond}    Fd,m,<label | const>
  255.  
  256. LFM{cond}{stack}    Fd,m,[Rn]{!}
  257. SFM{cond}{stack}    Fd,m,[Rn]{!}
  258. LFS{cond}{stack}    Rn{!},<fp register list>
  259. LFS{cond}{stack}    Rn{!},<fp register list>
  260.  
  261.     LFM, SFM, LFS and SFS use extended precision. The <fp register list>
  262.     is much as for LDM and STM, with restrictions: you must specify a
  263.     register or a sequence of registers, and the list must be compatible
  264.     with LFM and SFM - eg.
  265.     LFSFD R13!,{F3}        LFMFD F3,1,[R13]!    LFM F3,1,[R13],#12
  266.     SFSFD R13!,{F5-F0}    SFMFD F5,4,[R13]!    SFM F5,4,[R13,#-36]!
  267.     LFSDB R13,{F1,F0}    LFMDB F0,2,[R13]    LFM F0,2,[R13,#-24]
  268.     - for each row, all the instructions have the same effect.
  269.     Available stack types are DB, IA, EA, FD.
  270.     Note that example 2 wraps around - F5, F6, F7, F0 _in that order_.
  271.  
  272. * Floating point coprocessor register transfer
  273.  
  274. FLT{cond}prec{round}    Fn,Rd
  275. FIX{cond}{round}    Rd,Fn
  276. WFS, RFS, WFC, RFC:
  277.     xxx{cond}    Rd
  278.  
  279. * Floating point coprocessor data operations
  280.  
  281. ADF, MUF, SUF, RSF, DVF, RDF, POW, RPW, RMF, FML, FDV, FRD, POL:
  282.     xxx{cond}prec{round}    Fd,Fn,<Fm | #value>
  283.  
  284. MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
  285. SIN, COS, TAN, ASN, ACS, ATN, URD, NRM:
  286.     xxx{cond}prec{round}    Fd,<Fm | #value>
  287.  
  288. * Floating point coprocessor status transfer
  289.  
  290. CMF, CNF, CMFE, CNFE:
  291.     xxx{cond}    Fm,<Fn | #value>
  292.  
  293.  
  294. General co-processor instructions
  295. —————————————————————————————————
  296.  
  297. * Coprocessor data operations
  298.  
  299. CDO, CDP:
  300.     xxx{cond}    CP#,copro_opcode,Cd,Cn,Cm{,<const>}
  301.  
  302.     The values of copro_opcode and the optional constant must lie within
  303.     the range 0..15.
  304.  
  305. * Coprocessor data transfer
  306.  
  307. MCR, MCR:
  308.     xxx{cond}    CP#,<const1>,Rd,Cn,Cm{,<const2>}
  309.  
  310. LDC, STC:
  311.     xxx{cond}{L}{T}    CP#,Cd,[Rn]{,#offset}
  312.     xxx{cond}{L}    CP#,Cd,[Rn{,#offset}]{!}
  313.  
  314.     L and T may be specified in either order. So if you want an
  315.     unconditional LDC with both flags set, use LDCTL or LDCALLT since
  316.     LDCLT will be assembled as "LDC with T and L clear, if less than".
  317.     The T flag is retained for compatibility reasons; it is automatically
  318.     set anyway.
  319.  
  320.  
  321. Assembler directives
  322. ————————————————————
  323.  
  324. * Conditional - will STOP if expression is FALSE:
  325.  
  326. ASSERT    <expression>
  327.  
  328.     Bit 4 of the OPT value controls ASSERT. When it and bit 1 are zero,
  329.     ASSERTs are ignored.
  330.  
  331. * Constants
  332.  
  333. =    <const|string>
  334.     The bug causing an error when used in the form
  335.         .label = "something"
  336.     has been fixed.
  337.  
  338. EQUFS, EQUFD, EQUFE, EQUFP, EQUF
  339.     xxx    <const>
  340.  
  341. also the DC.. and |.. equivalents
  342.  
  343.     These directives accept an expression that evaluates to either an
  344.     integer or a real number. The result is then converted into the
  345.     required precision and stored in the object code at P%, or O% if
  346.     indirect assembly is being used. EQUF is a synonym for EQUFD.
  347.  
  348.     directive    EQUFS    EQUFD    EQUFE    EQUFP
  349.     bytes used    4    8    12    12
  350.  
  351. EQUP, DCP, P
  352.     xxx    <string>,<const>
  353.     xxx    <const>,<string>
  354.     Fixed-length string allocation. If the string is too short, then the
  355.     remaining space is padded with nulls; if it is too long, it is
  356.     truncated to the specified length.
  357.  
  358. EQUPW, DCPW, PW
  359.     xxx    <pad_byte>,<string>,<const>
  360.     xxx    <pad_byte>,<const>,<string>
  361.     Like EQUP, except that you specify the padding byte.
  362.  
  363. EQUZ, DCZ, Z
  364.     xxx    <string>
  365.     EQUS with automatic zero termination
  366.  
  367. EQUZA, DCZA, ZA
  368.     xxx    <string>
  369.     Equivalent to EQUZ followed by ALIGN
  370.  
  371.     Note: *ALL* the EQU... directives (and their equivalents) may have
  372.     their arguments repeated as described in the Extensions section.
  373.  
  374. FILL, %
  375.     xxx{B|W|D}    <const>{,{<value>}}
  376.     Allocates <const> bytes of memory, initialised to <value> (or 0).
  377.     B, W and D represent data lengths as for EQU; if omitted, then byte
  378.     length is assumed. If the comma is present but no fill value, this is
  379.     equivalent to adding the constant to P% (and O% if appropriate).
  380.  
  381. FILE    <filename>
  382.     Loads the specified file, allocating just enough space for it.
  383.  
  384. ^    <offset>
  385.     Initialises the workspace address pointer to the given value.
  386.     This is used and updated by #.
  387.     Typical use:
  388.         ^ 0
  389.         ...
  390.         # flags, 4
  391.         ...
  392.         LDRW    R0,flags
  393.  
  394. #    <variable>, <length>
  395.     Sets the variable to the current value of the workspace address
  396.     pointer, which is then incremented by <length>.
  397.     This does not alter P% or O%.
  398.     (Note: the variable is assigned before the length is evaluated.)
  399.  
  400. COND    <cond>
  401.     Sets the condition code for use with = (when used as a condition
  402.     code). It may be supplied as a condition code literal, a number (0 to
  403.     15), or a string containing a condition code literal. For example,
  404.     all of the following are equivalent:
  405.         COND    7        ; number
  406.         COND    VC        ; condition code literal
  407.         COND    vc        ; condition code literal
  408.         COND    "Vc"        ; string containing cond. code lit.
  409.     Example code:
  410.         COND    LT        ; select LT condition code
  411.         MOV=    R0,#2        ; MOVLT  R0,#2
  412.         MOV=S    R1,R2        ; MOVLTS R1,R2
  413.  
  414.  
  415. Notes
  416. —————
  417.  
  418. * Registers are specified in the following form:
  419.  
  420.     ARM registers:            R0..R15
  421.         using APCS-R names:    A1..A4 V1..V6 SL FP IP SP LR PC
  422.     Floating-point registers:    F0..F7
  423.     General co-processor registers:    C0..C15
  424.  
  425.   To help cope with any potential name clashes, the floating point and APCS-R
  426.   register names (except for PC) must be terminated with some character not
  427.   valid in a variable name in order to be recognised; they are otherwise
  428.   treated as part of a variable name.
  429.  
  430. * Coprocessor numbers (CP#) may be specified using either of the following
  431.   forms:
  432.  
  433.     P0..P15
  434.     CP0..CP15
  435.  
  436. * Wherever a register or coprocessor number is specified, an expression may
  437.   be substituted in the usual manner allowed by BASIC V. This module employs
  438.   the routines used within BASIC to evaluate all expressions (eg. register
  439.   numbers, offsets and labels) and hence its interpretation of expressions is
  440.   guaranteed to be the same as BASIC.
  441.  
  442.  
  443. Credits
  444. ———————
  445.  
  446.   Adrian Lees (last known, AFAIK, at A.M.Lees-CSEE93@@cs.bham.ac.uk):
  447.   - for the original ExtBas and the EQU comma extension, and for the use of
  448.     some of his code
  449.  
  450.   Michael Rozdoba (formerly of TechForum / Acorn Answers):
  451.   - for including the "General recursive method for Rb := Ra * C, C a
  452.     constant" from Appendix C of the manual for Acorn's desktop assembler,
  453.     and the late Acorn Computing (Sept 1994) for printing it;
  454.   - for the division code generator (Archimedes World, May 1995), which was
  455.     included, slightly trimmed, and debugged to handle top-bit-set unsigned
  456.     numbers properly... I hope!
  457.  
  458.   Dominic Symes of !Zap fame (dominic.symes@armltd.co.uk):
  459.   - for pointing out that ANDEQ R0,R0,R0 could usefully be replaced by DCD 0
  460.  
  461.   Martin Willers (m.willers@tu-bs.de):
  462.   - for bug hunting :-)
  463.  
  464.   Reuben Thomas (rrt1001@cam.ac.uk):
  465.   - for pointing out it might be useful to disable the APCS register names,
  466.     suggesting B/W/D suffix for FILL (and %) and -ve immediate constants, and
  467.     bug encountering
  468.  
  469.   Mohsen Alshayef (mohsen@qatar.net.qa):
  470.   - for some useful long MUL, STRH and [CS]PSR info
  471.